/*
 * SensorSampler.java
 *
 * Copyright (c) 2008-2010 Sun Microsystems, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
package org.sunspotworld.demo;

import com.sun.spot.io.j2me.radiogram.*;
import com.sun.spot.peripheral.IBattery;
import com.sun.spot.peripheral.IPowerController;
import com.sun.spot.peripheral.Spot;
import com.sun.spot.resources.Resources;
import com.sun.spot.resources.transducers.ITriColorLED;
import com.sun.spot.resources.transducers.ILightSensor;
import com.sun.spot.resources.transducers.ITemperatureInput;
import com.sun.spot.util.Utils;
import java.util.Calendar;
import java.util.Date;
import javax.microedition.io.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
 * This application is the 'on SPOT' portion of the WSN/DTN System. It
 * periodically samples a sensor value on the SPOT and transmits it to
 * a WSN/DTN Core-Engine Sender application
 * for storage in a database.
 *
 * @author: Vipul Gupta
 * @modified by: Laili Aidi - aidi@kth.se
 * Condroid Summer CSD 2011 - KTH
 */
public class SensorSampler extends MIDlet {

    private static final int DATA_SINK_PORT = 70;
    private static final int SAMPLE_PERIOD = 10 * 1000;  // in milliseconds

    protected void startApp() throws MIDletStateChangeException {
        RadiogramConnection obRadioConn = null;
        Datagram obDatagram = null;
        String obStrSpotID = System.getProperty("IEEE_ADDRESS");

        ITemperatureInput tempSensor = (ITemperatureInput) Resources.lookup(ITemperatureInput.class);
        ILightSensor lightSensor = (ILightSensor) Resources.lookup(ILightSensor.class);
        ITriColorLED led = (ITriColorLED) Resources.lookup(ITriColorLED.class, "LED7");
        IPowerController power = Spot.getInstance().getPowerController();
        IBattery battery = power.getBattery();

        //IAccelerometer3D accel = (IAccelerometer3D)  Resources.lookup(IAccelerometer3D.class);

        System.out.println("Starting sensor sampler application on " + obStrSpotID + " ...");

        // Listen for downloads/commands over USB connection
        new com.sun.spot.service.BootloaderListenerService().getInstance().start();

        try {
            // Open up a broadcast connection at the data sink port
            // where the 'on Desktop' portion of this demo is listening
            obRadioConn = (RadiogramConnection) Connector.open("radiogram://broadcast:" + DATA_SINK_PORT);
            obDatagram = obRadioConn.newDatagram(obRadioConn.getMaximumLength());
        } catch (Exception e) {
            System.err.println("Exception 1: " + e + " in connection initialization.");
            notifyDestroyed();
        }

        Calendar obCal = Calendar.getInstance();
        String obStrCalender = null;
        long obLongNow = 0L;
        int obIntLight = 0;
        double obDoubTemp = 0;
        double obDoubBattery = 0;

        while (true) {
            try {
                // Get the current time and sensor obIntLight
                obLongNow = System.currentTimeMillis();
                obIntLight = lightSensor.getValue();
                obDoubTemp = tempSensor.getCelsius();
                obDoubBattery = battery.getBatteryLevel();

                // Flash an LED to indicate a sampling event
                led.setRGB(255, 255, 255);
                led.setOn();
                Utils.sleep(50);
                led.setOff();

                obCal.setTime(new Date(obLongNow));
                obStrCalender = obCal.get(Calendar.YEAR) + "-"
                        + (1 + obCal.get(Calendar.MONTH)) + "-"
                        + obCal.get(Calendar.DAY_OF_MONTH) + " "
                        + obCal.get(Calendar.HOUR_OF_DAY) + ":"
                        + obCal.get(Calendar.MINUTE) + ":"
                        + obCal.get(Calendar.SECOND);

                // Package our identifier, timestamp and sensor obIntLight into a radio datagram and send it.
                obDatagram.reset();
                //obDatagram.writeUTF(obStrSpotID);
                obDatagram.writeUTF(obStrCalender);
                obDatagram.writeInt(obIntLight);
                obDatagram.writeDouble(obDoubTemp);
                obDatagram.writeDouble(obDoubBattery);
                obRadioConn.send(obDatagram);
                System.out.println("Mote ID: " + obStrSpotID + ", sending at " + obStrCalender + ", Light is " + obIntLight + ", Temperature is " + obDoubTemp + ", Battery is " + obDoubBattery);

                // Go to sleep to conserve battery
                Utils.sleep(6000 - (System.currentTimeMillis() - obLongNow));
                // Go to sleep to conserve battery
                Utils.sleep(SAMPLE_PERIOD - (System.currentTimeMillis() - obLongNow));
            } catch (Exception e) {
                System.err.println("Exception 2:" + e + " while collecting/sending sensor sample.");
            }
        }
    }

    protected void pauseApp() {
        // This will never be called by the Squawk VM
    }

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        // Only called if startApp throws any exception other than MIDletStateChangeException
    }
}
